package blockingqueueDemo;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class MyBlockingQueueCondition implements MyBlockingQueue {
    private Queue<Object> queue;
    private int limit = 16;
    private ReentrantLock lock = new ReentrantLock();
    private Condition notEmpty = lock.newCondition();
    private Condition notFull = lock.newCondition();

    public MyBlockingQueueCondition(int limit) {
        this.limit = limit;
        queue = new LinkedList<Object>();
    }

    public void put(Object o) throws InterruptedException {
        lock.lockInterruptibly();
        try {
            while (queue.size() == limit)
                notFull.await();
            queue.add(o);
            notEmpty.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public Object get() throws InterruptedException {
        lock.lockInterruptibly();
        try {
            while (queue.size() == 0)
                notEmpty.await();
            Object item = queue.remove();
            notFull.signalAll();
            return item;
        } finally {
            lock.unlock();
        }
    }

    public int size() throws InterruptedException {
        lock.lockInterruptibly();
        try {
            return queue.size();
        } finally {
            lock.unlock();
        }

    }
}
